package utilities;

import java.util.ArrayList;

import dataobjects.Direction;
import dataobjects.Position;

public class Utilities {
	
	//TODO: Analyze different "branching" patterns for max search efficiency.

	public static final ArrayList<Direction> getDfsBranches(Direction dir){
		ArrayList<Direction> dirs = new ArrayList<Direction>();
		switch (dir) {
		case NORTH:
			dirs.add(Direction.NORTH);
			dirs.add(Direction.EAST);
			dirs.add(Direction.WEST);
			dirs.add(Direction.SOUTH);
			break;
		case SOUTH:
			dirs.add(Direction.EAST);
			dirs.add(Direction.SOUTH);
			dirs.add(Direction.WEST);
			dirs.add(Direction.NORTH);
			break;
		case EAST:
			dirs.add(Direction.EAST);
			dirs.add(Direction.NORTH);
			dirs.add(Direction.SOUTH);
			dirs.add(Direction.WEST);
			break;
		case WEST:
			dirs.add(Direction.NORTH);
			dirs.add(Direction.WEST);
			dirs.add(Direction.SOUTH);
			dirs.add(Direction.EAST);
			break;
		default:
			dirs.add(Direction.NORTH);
		dirs.add(Direction.SOUTH);
		dirs.add(Direction.EAST);
		dirs.add(Direction.WEST);
		break;
		}
		return dirs;
	}

	public static final ArrayList<Direction> getBackDfsBranches(Position pos, Position goal){
		ArrayList<Direction> dirs = new ArrayList<Direction>();
		switch (pos.getDir()) {
		case NORTH:
			dirs.add(Direction.NORTH);
			if (pos.getX() < goal.getX()){
				dirs.add(Direction.EAST);
				dirs.add(Direction.WEST);
			} else {
				dirs.add(Direction.WEST);
				dirs.add(Direction.EAST);
			}
			break;
		case SOUTH:
			dirs.add(Direction.SOUTH);
			if (pos.getX() < goal.getX()){
				dirs.add(Direction.EAST);
				dirs.add(Direction.WEST);
			} else {
				dirs.add(Direction.WEST);
				dirs.add(Direction.EAST);
			}
			break;
		case EAST:
			dirs.add(Direction.EAST);
			if (pos.getY() < goal.getY()){
				dirs.add(Direction.NORTH);
				dirs.add(Direction.SOUTH);
			} else {
				dirs.add(Direction.SOUTH);
				dirs.add(Direction.NORTH);
			}
			break;
		case WEST:
			dirs.add(Direction.WEST);
			if (pos.getY() < goal.getY()){
				dirs.add(Direction.NORTH);
				dirs.add(Direction.SOUTH);
			} else {
				dirs.add(Direction.SOUTH);
				dirs.add(Direction.NORTH);
			}
			break;
		default:
			dirs.add(Direction.NORTH);
			dirs.add(Direction.SOUTH);
			dirs.add(Direction.EAST);
			dirs.add(Direction.WEST);
			break;
		}
		return dirs;

	}
	
	public static final ArrayList<Direction> getSafeHvaDfsBranches(Direction dir){
		ArrayList<Direction> dirs = new ArrayList<Direction>();
		switch (dir) {
		case NORTH:
			dirs.add(Direction.NORTH);
			dirs.add(Direction.EAST);
			dirs.add(Direction.WEST);
			break;
		case SOUTH:
			dirs.add(Direction.SOUTH);
			dirs.add(Direction.EAST);
			dirs.add(Direction.WEST);
			break;
		case EAST:
			dirs.add(Direction.EAST);
			dirs.add(Direction.NORTH);
			dirs.add(Direction.SOUTH);
			break;
		case WEST:
			dirs.add(Direction.WEST);
			dirs.add(Direction.NORTH);
			dirs.add(Direction.SOUTH);
			break;
		default:
			dirs.add(Direction.NORTH);
			dirs.add(Direction.SOUTH);
			dirs.add(Direction.EAST);
			dirs.add(Direction.WEST);
			break;	
		}
		return dirs;
	}
	
	public static final Direction getReverseDirection(Direction dir){
		switch (dir) {
		case NORTH:
			return Direction.SOUTH;
		case SOUTH:
			return Direction.NORTH;
		case EAST:
			return Direction.WEST;
		case WEST:
			return Direction.EAST;
		default:
			return Direction.UNKNOWN;
		}
	}

	public static final Position getReverseDirection(Position pos){
		Position reverse = new Position(pos.getX(), pos.getY());
		switch (pos.getDir()) {
		case NORTH:
			pos.setDir(Direction.SOUTH);
			break;
		case SOUTH:
			pos.setDir(Direction.NORTH);
			break;
		case EAST:
			pos.setDir(Direction.WEST);
			break;
		case WEST:
			pos.setDir(Direction.EAST);
			break;
		default:
			break;
		}
		return reverse;
	}


}
